bitkeeper revision 1.1159.1.50 (411cafaaPlpV28_c19BEAsmasMfTcg)
authormjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Fri, 13 Aug 2004 12:10:18 +0000 (12:10 +0000)
committermjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Fri, 13 Aug 2004 12:10:18 +0000 (12:10 +0000)
Hacking to try to get migrate to localhost going.

tools/libxc/xc_linux_restore.c
tools/python/xen/xend/XendDomain.py
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xend/server/SrvDomain.py
tools/xfrd/xen_domain.c
tools/xfrd/xen_domain.h
tools/xfrd/xfrd.c

index 62050c83eba91bf87a7141b6934f939b76b66a5c..71b473d10c26f348ac348557b3f21554a7b425fd 100644 (file)
@@ -224,7 +224,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
 
     /* XXX create domain on CPU=-1 so that in future it auto load ballances by default */
     if ( xc_domain_create( xc_handle,  nr_pfns * (PAGE_SIZE / 1024),
-                          name, -1, &dom ) )
+                          "", -1, &dom ) )
     {
        xcio_error(ioctxt, "Could not create domain. pfns=%d, %dKB",
                   nr_pfns,nr_pfns * (PAGE_SIZE / 1024));
index bffbdee46b35e9f8a84d55dd27b8db42be46ba8b..7dead8f82051ba883d1d14a97cb1b1ff20ab9859 100644 (file)
@@ -197,7 +197,11 @@ class XendDomain:
         """
         self.domain_by_id[info.id] = info
         self.domain_db[info.id] = info.sxpr()
-        self.domain_by_name[info.name] = info
+        for k, d in self.domain_by_name.items():
+            if k != d.name:
+                del self.domain_by_name[k]
+        if info.name:
+            self.domain_by_name[info.name] = info
         self.sync_domain(info.id)
         if notify: eserver.inject('xend.domain.created', [info.name, info.id])
 
@@ -207,12 +211,13 @@ class XendDomain:
         @param id:     domain id
         @param notify: send a domain died event if true
         """
+        for info in self.domain_by_name.values():
+            if info.id == id:
+                del self.domain_by_name[info.name]
         if id in self.domain_by_id:
             info = self.domain_by_id[id]
-            if notify: eserver.inject('xend.domain.died', [info.name, info.id])
-            if info.name in self.domain_by_name:
-                del self.domain_by_name[info.name]
             del self.domain_by_id[id]
+            if notify: eserver.inject('xend.domain.died', [info.name, info.id])
         if id in self.domain_db:
             del self.domain_db[id]
             self.db.delete(id)
@@ -223,6 +228,10 @@ class XendDomain:
         """
         self.reap_cancel()
         domlist = xc.domain_getinfo()
+        #for d in domlist:
+        #    print 'reap> xen:  ', d['dom'], d
+        #for d in self.domain_by_id.values():
+        #    print 'reap> xend: ', d.id, d.info
         casualties = []
         for d in domlist:
             dead = 0
@@ -240,9 +249,12 @@ class XendDomain:
                 log.debug('XendDomain>reap> shutdown id=%s reason=%s', id, reason)
                 if reason in ['suspend']:
                     dominfo = self.domain_by_id.get(id)
-                    name = (dominfo and dominfo.name) or '??'
-                    eserver.inject('xend.domain.suspended', [name, id])
-                    continue
+                    if dominfo.is_terminated():
+                        log.debug('XendDomain>reap> Suspended domain died id=%s', id)
+                    else:
+                        name = (dominfo and dominfo.name) or '??'
+                        eserver.inject('xend.domain.suspended', [name, id])
+                        continue
                 if reason in ['poweroff', 'reboot']:
                     self.domain_restart_schedule(id, reason)
             destroyed += 1
@@ -257,6 +269,10 @@ class XendDomain:
         """
         self.refresh_cancel()
         domlist = xc.domain_getinfo()
+        #for d in domlist:
+        #    print 'refresh> xen:  ', d['dom'], d
+        #for d in self.domain_by_id.values():
+        #    print 'refresh> xend: ', d.id, d.info
         # Index the domlist by id.
         # Add entries for any domains we don't know about.
         doms = {}
@@ -344,6 +360,15 @@ class XendDomain:
         deferred.addCallback(cbok)
         return deferred
 
+    def domain_setname(self, dom, name):
+        """Set the name of a domain.
+        For internal use only.
+
+        @param dom: domain id
+        @param name: domain name
+        """
+        return xc.domain_setname(dom=dom, name=name)
+
     def domain_restart(self, dominfo):
         """Restart a domain.
 
@@ -358,22 +383,23 @@ class XendDomain:
         deferred.addCallback(cbok)
         return deferred        
 
-    def domain_configure(self, id, config):
+    def domain_configure(self, id, vmconfig):
         """Configure an existing domain. This is intended for internal
         use by domain restore and migrate.
 
-        @param id:     domain id
-        @param config: configuration
+        @param id:       domain id
+        @param vmconfig: vm configuration
         @return: deferred
         """
-        print 'domain_configure>', id, config
+        print 'domain_configure>', id, vmconfig
+        config = sxp.child_value(vmconfig, 'config')
         dominfo = self.domain_lookup(id)
         print 'domain_configure>', 'dominfo=', dominfo
         for dinfo in self.domain_by_id.values():
-            print 'domain', dinfo.id, dinfo.name
-        log.debug('domain_configure> id=%s config=%s', id, str(config))
+            print 'domain', 'id=', dinfo.id, 'name=', dinfo.name
+        log.debug('domain_configure> id=%s config=%s', str(id), str(config))
         if dominfo.config:
-            raise XendError("Domain already configured: " + dominfo.name)
+            raise XendError("Domain already configured: " + dominfo.id)
         def cbok(dominfo):
             self._add_domain(dominfo)
             return dominfo
index 472cc0f74c8fb73e7428a33050b8656f16a59823..ce01d28b0a542478662bcb19f9cb822c3e9b6ad3 100644 (file)
@@ -475,6 +475,8 @@ class XendDomainInfo:
         if not dominfo:
             return
         print 'check_name>', 'dom=', dominfo.name, dominfo.dom, 'self=', name, self.dom
+        if dominfo.is_terminated():
+            return
         if not self.dom or (dominfo.dom != self.dom):
             raise VmError('vm name clash: ' + name)
         
@@ -490,6 +492,8 @@ class XendDomainInfo:
         try:
             self.name = sxp.child_value(config, 'name')
             self.check_name(self.name)
+            if self.restore and self.dom:
+                xc.domain_setname(self.dom, self.name)
             self.memory = int(sxp.child_value(config, 'memory'))
             if self.memory is None:
                 raise VmError('missing memory size')
@@ -629,6 +633,7 @@ class XendDomainInfo:
             if self.restart_pending():
                 self.console.deregisterChannel()
             else:
+                log.debug('Closing console, domain %s', self.id)
                 self.console.close()
         chan = xend.getDomChannel(self.dom)
         if chan:
index 8975148819aafed29e020e16fceedc939a6b8b11..aed8fd7e57848e598012ba74edadb8c35ec59318 100644 (file)
@@ -21,10 +21,14 @@ class SrvDomain(SrvDir):
         self.xconsole = XendConsole.instance()
 
     def op_configure(self, op, req):
+        """Configure an existing domain.
+        Configure is unusual in that it requires a domain id,
+        not a domain name.
+        """
         fn = FormFn(self.xd.domain_configure,
-                    [['dom', 'str'],
+                    [['dom', 'int'],
                      ['config', 'sxpr']])
-        deferred = fn(req.args, {'dom': self.dom.name})
+        deferred = fn(req.args, {'dom': self.dom.dom})
         deferred.addErrback(self._op_configure_err, req)
         return deferred
 
index a5d18c0199bd0d1b07a65405c7bbea45a01da7f8..2f6d0fa8f2be3c78934812a45036ba89a3b780a9 100644 (file)
@@ -304,7 +304,44 @@ int xen_domain_configure(uint32_t dom, char *vmconfig, int vmconfig_n){
                             CURLFORM_COPYNAME,     "op",
                             CURLFORM_COPYCONTENTS, "configure",
                             CURLFORM_END);
+    if(formcode){
+        eprintf("> Error adding op field.\n");
+        err = -EINVAL;
+        goto exit;
+    }
+    // POST the form.
+    curl_easy_setopt(curl, CURLOPT_HTTPPOST, form);
+    err = curlresult(curl);
+  exit:
+    if(curl) curl_easy_cleanup(curl);
+    if(form) curl_formfree(form);
+    dprintf("< err=%d\n", err);
+    return err;
+}
+
+/** Get xend to unpause a domain.
+ *
+ * @param dom domain id
+ * @return 0 on success, error code otherwise
+ */
+int xen_domain_unpause(uint32_t dom){
+    int err = 0;
+    CURL *curl = NULL;
+    char url[128] = {};
+    int url_n = sizeof(url);
+    struct curl_httppost *form = NULL, *last = NULL;
+    CURLFORMcode formcode = 0;
 
+    dprintf("> dom=%u\n", dom);
+
+    err = curlsetup(&curl, url, url_n, "http://localhost:%d/xend/domain/%u", XEND_PORT, dom);
+    if(err) goto exit;
+
+    // Op field.
+    formcode = curl_formadd(&form, &last,
+                            CURLFORM_COPYNAME,     "op",
+                            CURLFORM_COPYCONTENTS, "unpause",
+                            CURLFORM_END);
     if(formcode){
         eprintf("> Error adding op field.\n");
         err = -EINVAL;
index 4618c642b71f28a7239cb7b61bf40358a6d32253..4b2e1c7e048a5f665a2742367fb6b445a9856008 100644 (file)
@@ -12,4 +12,5 @@ extern int xen_domain_rcv(IOStream *io, uint32_t *dom, char **vmconfig, int *vmc
 
 
 extern int xen_domain_configure(uint32_t dom, char *vmconfig, int vmconfig_n);
+extern int xen_domain_unpause(uint32_t dom);
 #endif
index 3d0cfa3e667445977032f04fa4accc7c6ac3c07f..c5abcdcf1b6ee852bdf185391919a97a82a2c64f 100644 (file)
@@ -605,13 +605,18 @@ int xfr_send_state(XfrState *state, Conn *xend, Conn *peer){
     // Send xfr message and the domain state.
     err = xfr_send_xfr(peer, state->vmid);
     if(err) goto exit;
+    dprintf(">*** Sending domain %u\n", state->vmid);
     err = xen_domain_snd(xend, peer->out,
                          state->vmid, state->vmconfig, state->vmconfig_n);
+    dprintf(">*** Sent domain %u\n", state->vmid);
     if(err) goto exit;
     // Sending the domain suspends it, and there's no way back.
     // So destroy it now. If anything goes wrong now it's too late.
+    dprintf(">*** Destroying domain %u\n", state->vmid);
     err = xfr_vm_destroy(xend, state->vmid);
     if(err) goto exit;
+    err = xfr_error(peer, err);
+    if(err) goto exit;
     IOStream_flush(peer->out);
     // Read the response from the peer.
     err = Conn_sxpr(peer, &sxpr);
@@ -778,14 +783,21 @@ int xfr_save(Args *args, XfrState *state, Conn *xend, char *file){
 int xfr_recv(Args *args, XfrState *state, Conn *peer){
     int err = 0;
     time_t t0 = time(NULL), t1;
+    Sxpr sxpr;
 
     dprintf(">\n");
     err = xen_domain_rcv(peer->in, &state->vmid_new, &state->vmconfig, &state->vmconfig_n);
     if(err) goto exit;
-
+    // Read from the peer. This is just so we wait before configuring.
+    // When migrating to the same host the peer must destroy the domain
+    // before we configure the new one.
+    err = Conn_sxpr(peer, &sxpr);
+    if(err) goto exit;
+    sleep(2);
     err = xen_domain_configure(state->vmid_new, state->vmconfig, state->vmconfig_n);
     if(err) goto exit;
-
+    err = xen_domain_unpause(state->vmid_new);
+    if(err) goto exit;
     // Report new domain id to peer.
     err = xfr_send_xfr_ok(peer, state->vmid_new);
     if(err) goto exit;